package hsl.study.controller;


import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author: hsl
 * @CreateDate: 2025/7/31 16:04
 * @Version: 1.0
 */


@RestController
@RequestMapping("/promptTemplate")
public class PromptTemplateController {

    // v1 通过ChatModel实现stream流的形式进行结果输出
    @Resource(name = "deepseek")
    private OpenAiChatModel deepSeek;
    @Resource(name = "qwenPlus")
    private OpenAiChatModel qwenPlus;

    // v2 通过ChatClient实现stream流的形式进行结果输出
    @Resource(name = "deepseekChatClient")
    private ChatClient deepSeekClient;
    @Resource(name = "qwenPlusChatClient")
    private ChatClient qwenClient;

    @Value("classpath:/prompttemplate/usertemplate.txt")
    private org.springframework.core.io.Resource userTemplate;

    /**
     * 测试promptTemplate 基本使用 就是通过占位符来进行实现
     *
     * @param topic
     * @param output_format
     * @param wordCount
     * @return http://localhost:7006/promptTemplate/chat1?topic=java&output_format=html&wordCount=200
     */
    @GetMapping("/chat1")
    public Flux<String> chat1(String topic, String output_format, String wordCount) {
        PromptTemplate promptTemplate = new PromptTemplate(
                "讲一个关于{topic}的故事" +
                        "并以{output_format}格式输出" +
                        "字数控制在{wordCount}左右");

        //promptTemplate --> prompt
        Prompt prompt = promptTemplate.create(Map.of(
                "topic", topic,
                "output_format", output_format,
                "wordCount", wordCount));
        return deepSeekClient.prompt(prompt).stream().content();
    }


    /**
     * 通过promptTemplate 读取模版文件进行prompt的创建
     *
     * @param topic
     * @param output_format
     * @return  http://localhost:7006/promptTemplate/chat2?topic=java&output_format=html
     */
    @GetMapping("/chat2")
    public String chat2(String topic, String output_format) {

        PromptTemplate promptTemplate = new PromptTemplate(userTemplate);

        Prompt prompt = promptTemplate.create(Map.of(
                "topic", topic,
                "output_format", output_format));
        return deepSeekClient.prompt(prompt).call().content();
    }

    /**
     * @param sysTopic  系统消息 界定AI是处理哪方面的业务助手 规定边界与区间的作用
     * @param userTopic 用户消息 用户所提问的问题
     * @return
     *  http://localhost:7006/promptTemplate/chat3?sysTopic=法律&userTopic=知识产权法
     *
     *  http://localhost:7006/promptTemplate/chat3?sysTopic=法律&userTopic=鱼香肉丝
     */
    @GetMapping("/chat3")
    public String chat3(String sysTopic, String userTopic) {

        //1. SystemPrompt
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate("你是一个{sysTopic}助手," +
                "只回答{sysTopic}其他无可奉告，以HTML格式进行结果输出");
        Message sysMessage = systemPromptTemplate.createMessage(Map.of("sysTopic", sysTopic));
        //2. PromptTemplate
        PromptTemplate promptTemplate = new PromptTemplate("解释一下{userTopic}");
        Message userMessage = promptTemplate.createMessage(Map.of("userTopic", userTopic));
        // 3.组合[关键] 多个massage --> prompt
        Prompt prompt = new Prompt(List.of(sysMessage, userMessage));
        //4. 调用LLM 进行结果处理
        return deepSeekClient.prompt(prompt).call().content();
    }

    /**
     * 代码中指明AI助手的处理边界 专事专做
     *
     * @param question 用户输入的问题
     * @return
     * http://localhost:7006/promptTemplate/chat4?question=北京天气怎么样
     */
    @GetMapping("/chat4")
    public String chat4(String question) {
        //1. 系统消息
        SystemMessage systemMessage = new SystemMessage("你是一个java编程助手，拒绝回答非技术问题");
        //2. 用户消息
        UserMessage userMessage = new UserMessage(question);
        //3. 组合 系统消息+用户消息 --> prompt(完整提示词)
        Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
        //4. 调用LLM进行结果处理
        String result = deepSeek.call(prompt).getResult().getOutput().getText();
        System.out.println("result = " + result);
        return result;
    }

    /**
     * stream流 链式调用
     * @param question
     * @return http://localhost:7006/promptTemplate/chat4?question=北京天气怎么样
     */
    @GetMapping("/chat5")
    public Flux<String> chat5(String question) {
        return deepSeekClient.prompt()
                .system("你是一个java编程助手，拒绝回答非技术问题")
                .user(question)
                .stream()
                .content();
    }
}
